import "./global";
import { ExtendableError } from "./error";
// { utils, cast, validate, debug, logger }
import * as node from "./node";

let _utils = node.utils;
_utils.run = function(expression, context = window) {
    return Function.apply(Function, ['context', `with(context) { return ${expression} }`])(context, expression);
}
export let utils = _utils;

export let cast = node.cast;
export let validate = node.validate;
export let debug = node.debug;
export let logger = node.logger;
export let Error = node.Error;

import * as _browser from "./browser";
export let browser = _browser;

import WebStorageCache from "./web-cache-storage";

function copyTextToClipboard(text) {
    let ret = false;
    let textArea = document.createElement("textarea");

    //
    // *** This styling is an extra step which is likely not required. ***
    //
    // Why is it here? To ensure:
    // 1. the element is able to have focus and selection.
    // 2. if element was to flash render it has minimal visual impact.
    // 3. less flakyness with selection and copying which **might** occur if
    //    the textarea element is not visible.
    //
    // The likelihood is the element won't even render, not even a flash,
    // so some of these are just precautions. However in IE the element
    // is visible whilst the popup box asking the user for permission for
    // the web page to copy to the clipboard.
    //

    // Place in top-left corner of screen regardless of scroll position.
    textArea.style.position = 'fixed';
    textArea.style.top = 0;
    textArea.style.left = 0;

    // Ensure it has a small width and height. Setting to 1px / 1em
    // doesn't work as this gives a negative w/h on some browsers.
    textArea.style.width = '2em';
    textArea.style.height = '2em';

    // We don't need padding, reducing the size if it does flash render.
    textArea.style.padding = 0;

    // Clean up any borders.
    textArea.style.border = 'none';
    textArea.style.outline = 'none';
    textArea.style.boxShadow = 'none';

    // Avoid flash of white box if rendered for any reason.
    textArea.style.background = 'transparent';


    textArea.value = text;

    document.body.appendChild(textArea);

    textArea.select();

    try {
        ret = document.execCommand('copy');
        // var msg = successful ? 'successful' : 'unsuccessful';
        // console.log('Copying text command was ' + msg);
    } catch (err) {
        // console.log('Oops, unable to copy');
    }

    document.body.removeChild(textArea);
    return ret;
}


class ClipboardDataError extends ExtendableError {
    constructor() {
        super("set ClipboardData error");
    }
}

/**
 * wx
 * Google Chrome 44, Firefox 42.0a1 and IE 11.0.8600.17814.
 * ali (*)
 *
 * @throws ClipboardDataError
 * @param data
 * @return {Promise<any>}
 */
export function setClipboardData(data) {
    let error = new ClipboardDataError();
    return new Promise(function (resolve, reject) {
        let isSuccess = copyTextToClipboard(data);
        if (isSuccess) {
            resolve();
        } else {
            reject(error);
        }
    })
}

export let __webStorageCache = new WebStorageCache();
window.__webStorageCache = __webStorageCache;

/** 
 * 得到屏幕的大小
 */
export let getScreenWidth = function() {
    return screen.width > 0 ? screen.width : 0;
}

export let isPhoneSize = function(maxWidth = 768) {
    return getScreenWidth() < maxWidth && this.browser.detectMediaMacthes('(max-device-width: 769px)');
}

export let isPhoneWeixin = function() {
    return isPhoneSize() && this.browser.isLikeWeixin();
}

/**
 * 设置storage
 * 
 * @param {String} key 
 * @param {Any} data 
 * @param {Object} options 
 */
export function setStorageSync(key, data, options) {
    if (options && options.expire && options.expire instanceof Date) {
        options.exp = options.expire.valueOf() - new Date().valueOf();
    }
    return __webStorageCache.set(key, data, options);
}

/**
 * 获得storage中某个key的值
 * 
 * @param {String} key 
 */
export function getStorageSync(key) {
    return __webStorageCache.get(key);
}

/**
 * 删除某个值
 * 
 * @param {String} key 
 */
export function removeStorageSync(key) {
    return __webStorageCache.delete(key);
}


/**
 * 更新某个值
 * 
 * @param {*} key 
 * @param {*} value 
 * @param {*} options 
 * 
 * @returns {Boolean} isUpdated 
 */
export function updateStorageSync(key, value, options) {
    return __webStorageCache.replace(key, value, options);
}

/** 
 * 清空storage  
 */
export function clearStorageSync() {
    return __webStorageCache.clear();
}